
<!doctype html>
<html lang="zh" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
        <meta name="author" content="HENG">
      
      
      
        <link rel="prev" href="admin.html">
      
      
        <link rel="next" href="static.html">
      
      
      <link rel="icon" href="assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.20">
    
    
      
        <title>模板 - Django杂记</title>
      
    
    
      <link rel="stylesheet" href="assets/stylesheets/main.66ac8b77.min.css">
      
        
        <link rel="stylesheet" href="assets/stylesheets/palette.06af60db.min.css">
      
      


    
    
      
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
    <script>__md_scope=new URL(".",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
    
  </head>
  
  
    
    
      
    
    
    
    
    <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="deep-orange" data-md-color-accent="indigo">
  
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#django" class="md-skip">
          跳转至
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

  

<header class="md-header md-header--shadow" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="页眉">
    <a href="index.html" title="Django杂记" class="md-header__button md-logo" aria-label="Django杂记" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            Django杂记
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              模板
            
          </span>
        </div>
      </div>
    </div>
    
      
        <form class="md-header__option" data-md-component="palette">
  
    
    
    
    <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="deep-orange" data-md-color-accent="indigo"  aria-label="亮色模式"  type="radio" name="__palette" id="__palette_0">
    
      <label class="md-header__button md-icon" title="亮色模式" for="__palette_1" hidden>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
      </label>
    
  
    
    
    
    <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="cyan"  aria-label="暗色模式"  type="radio" name="__palette" id="__palette_1">
    
      <label class="md-header__button md-icon" title="暗色模式" for="__palette_0" hidden>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12c0-2.42-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
      </label>
    
  
</form>
      
    
    
      <script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
    
    
    
      <label class="md-header__button md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
      </label>
      <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="查找">
        
        <button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            正在初始化搜索引擎
          </div>
          <ol class="md-search-result__list" role="presentation"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header__source">
        <a href="https://github.com/lmliheng/codes" title="前往仓库" class="md-source" data-md-component="source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
  </div>
  <div class="md-source__repository">
    Heng's Codes
  </div>
</a>
      </div>
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    



<nav class="md-nav md-nav--primary" aria-label="导航栏" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="index.html" title="Django杂记" class="md-nav__button md-logo" aria-label="Django杂记" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>

    </a>
    Django杂记
  </label>
  
    <div class="md-nav__source">
      <a href="https://github.com/lmliheng/codes" title="前往仓库" class="md-source" data-md-component="source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
  </div>
  <div class="md-source__repository">
    Heng's Codes
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="index.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    主页
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="settings.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    配置文件
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="models.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    模型
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="urls.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    路由
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="view.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    视图
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="admin.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    管理员
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
    
  
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
      
      
      
        <label class="md-nav__link md-nav__link--active" for="__toc">
          
  
  <span class="md-ellipsis">
    模板
  </span>
  

          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <a href="template.html" class="md-nav__link md-nav__link--active">
        
  
  <span class="md-ellipsis">
    模板
  </span>
  

      </a>
      
        

<nav class="md-nav md-nav--secondary" aria-label="目录">
  
  
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      目录
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#django" class="md-nav__link">
    <span class="md-ellipsis">
      Django模板语言详解
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_1" class="md-nav__link">
    <span class="md-ellipsis">
      一、模板
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_2" class="md-nav__link">
    <span class="md-ellipsis">
      二、变量
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_3" class="md-nav__link">
    <span class="md-ellipsis">
      三、过滤器
    </span>
  </a>
  
    <nav class="md-nav" aria-label="三、过滤器">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-default" class="md-nav__link">
    <span class="md-ellipsis">
      1. default
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-length" class="md-nav__link">
    <span class="md-ellipsis">
      2. length
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#3-filesizeformat" class="md-nav__link">
    <span class="md-ellipsis">
      3. filesizeformat
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_4" class="md-nav__link">
    <span class="md-ellipsis">
      四、标签
    </span>
  </a>
  
    <nav class="md-nav" aria-label="四、标签">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-for" class="md-nav__link">
    <span class="md-ellipsis">
      1. for循环标签
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-ifelifelse" class="md-nav__link">
    <span class="md-ellipsis">
      2. if，elif和else标签
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#3-blockextends" class="md-nav__link">
    <span class="md-ellipsis">
      3. block和extends标签
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_5" class="md-nav__link">
    <span class="md-ellipsis">
      五、注释
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_6" class="md-nav__link">
    <span class="md-ellipsis">
      六、模板继承
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#html" class="md-nav__link">
    <span class="md-ellipsis">
      七、自动转义HTML
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_7" class="md-nav__link">
    <span class="md-ellipsis">
      八、方法调用
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_8" class="md-nav__link">
    <span class="md-ellipsis">
      九、多对多调用
    </span>
  </a>
  
    <nav class="md-nav" aria-label="九、多对多调用">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#_9" class="md-nav__link">
    <span class="md-ellipsis">
      正向查询
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#_10" class="md-nav__link">
    <span class="md-ellipsis">
      反向查询
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_11" class="md-nav__link">
    <span class="md-ellipsis">
      十、使用自定义标签和过滤器
    </span>
  </a>
  
    <nav class="md-nav" aria-label="十、使用自定义标签和过滤器">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#14" class="md-nav__link">
    <span class="md-ellipsis">
      评论总数： 14
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
    </ul>
  
</nav>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="static.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    静态资源
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="database.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    数据库
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="file.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    文件上传与生成
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="cron.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    定时任务
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="translator.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    流媒体
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="linux.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    部署笔记
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="codeplan.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    计划表项目搭建
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="fontend.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    前后端分离架构
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="question.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    常见问题
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="exe.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    应用程序
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="mkdocs.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    mkdocs笔记
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="markdown.html" class="md-nav__link">
        
  
  <span class="md-ellipsis">
    Markdown格式
  </span>
  

      </a>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="目录">
  
  
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      目录
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#django" class="md-nav__link">
    <span class="md-ellipsis">
      Django模板语言详解
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_1" class="md-nav__link">
    <span class="md-ellipsis">
      一、模板
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_2" class="md-nav__link">
    <span class="md-ellipsis">
      二、变量
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_3" class="md-nav__link">
    <span class="md-ellipsis">
      三、过滤器
    </span>
  </a>
  
    <nav class="md-nav" aria-label="三、过滤器">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-default" class="md-nav__link">
    <span class="md-ellipsis">
      1. default
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-length" class="md-nav__link">
    <span class="md-ellipsis">
      2. length
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#3-filesizeformat" class="md-nav__link">
    <span class="md-ellipsis">
      3. filesizeformat
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_4" class="md-nav__link">
    <span class="md-ellipsis">
      四、标签
    </span>
  </a>
  
    <nav class="md-nav" aria-label="四、标签">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-for" class="md-nav__link">
    <span class="md-ellipsis">
      1. for循环标签
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-ifelifelse" class="md-nav__link">
    <span class="md-ellipsis">
      2. if，elif和else标签
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#3-blockextends" class="md-nav__link">
    <span class="md-ellipsis">
      3. block和extends标签
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_5" class="md-nav__link">
    <span class="md-ellipsis">
      五、注释
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_6" class="md-nav__link">
    <span class="md-ellipsis">
      六、模板继承
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#html" class="md-nav__link">
    <span class="md-ellipsis">
      七、自动转义HTML
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_7" class="md-nav__link">
    <span class="md-ellipsis">
      八、方法调用
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_8" class="md-nav__link">
    <span class="md-ellipsis">
      九、多对多调用
    </span>
  </a>
  
    <nav class="md-nav" aria-label="九、多对多调用">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#_9" class="md-nav__link">
    <span class="md-ellipsis">
      正向查询
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#_10" class="md-nav__link">
    <span class="md-ellipsis">
      反向查询
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#_11" class="md-nav__link">
    <span class="md-ellipsis">
      十、使用自定义标签和过滤器
    </span>
  </a>
  
    <nav class="md-nav" aria-label="十、使用自定义标签和过滤器">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#14" class="md-nav__link">
    <span class="md-ellipsis">
      评论总数： 14
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          
            <div class="md-content" data-md-component="content">
              <article class="md-content__inner md-typeset">
                
                  

  
  


<h2 id="django">Django模板语言详解</h2>
<p>本节将介绍Django模版系统的语法。Django模版语言致力于在性能和简单性上取得平衡。</p>
<p>如果你有过其它编程背景，或者使用过一些在HTML中直接混入程序代码的语言，那么你需要记住，Django的模版系统并不是简单的将Python嵌入到HTML中。</p>
<h2 id="_1">一、模板</h2>
<p>模版是纯文本文件，可以生成任何基于文本的文件格式，比如HTML，XML，CSV等。</p>
<p>下面是一个小模版，它展示了一些基本的元素。</p>
<p>{% extends "base_generic.html" %}</p>
<p>{% block title %}{{ section.title }}{% endblock %}</p>
<p>{% block content %}</p>
<h1>{{ section.title }}</h1>

<p>{% for story in story_list %}</p>
<h2>
  <a href="{{ story.get\_absolute\_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
<p>{% endfor %}
{% endblock %}</p>
<h2 id="_2">二、变量</h2>
<p>变量看起来就像是这样： <code>{{ variable }}。</code></p>
<p>当模版引擎遇到一个变量，它将从上下文context中获取这个变量的值，然后用值替换掉它本身。</p>
<p>变量的命名包括任何字母数字以及下划线("_")的组合，最重要的是，<strong>变量名称中不能有空格或标点符号</strong>。</p>
<p>当模版系统渲染变量的时候遇到点(".")，它将以这样的顺序查询这个圆点具体代表的功能：</p>
<ul>
<li>字典查询（Dictionary lookup）</li>
<li>属性或方法查询（Attribute or method lookup）</li>
<li>数字索引查询（Numeric index lookup）</li>
</ul>
<p>如果你使用的变量不存在，模版系统将插入<code>string_if_invalid</code>选项的值，默认设置为''(空字符串)。</p>
<p>注意，像<code>{{ foo.bar }}</code>这种模版表达式中的“bar”，如果在模版上下文中存在，将解释为一个字面意义的字符串而不是使用变量bar的值 。</p>
<h2 id="_3">三、过滤器</h2>
<p>过滤器看起来是这样的：<code>{{ name | lower }}</code>。使用管道符号(<code>|</code>)来应用过滤器。该过滤器将文本转换成小写。</p>
<p>过滤器可以“链接”。一个过滤器的输出应用于下一个过滤器。例如：<code>{{ text|escape|linebreaks }}</code>就是一个常用的过滤器链，它首先转移文本内容，然后把文本行转成<code>&lt;p&gt;</code>标签。</p>
<p>一些过滤器带有参数。 过滤器的参数看起来像是这样： <code>{{ bio|truncatewords:30 }}</code>。 这将显示bio变量的前30个词。</p>
<p><strong>过滤器参数包含空格的话，必须用引号包起来。</strong>例如，使用逗号和空格去连接一个列表中的元素，你需要使用<code>{{ list|join:", " }}</code>。</p>
<p>Django提供了大约六十个内置的模版过滤器，很多时候你想要的功能，它都已经提供了，经常查看这些过滤器，发现新大陆吧。下面是一些常用的模版过滤器：</p>
<h3 id="1-default">1. default</h3>
<p>为false或者空变量提供默认值，像这样：</p>
<p>{{ value|default:"nothing" }}</p>
<h3 id="2-length">2. length</h3>
<p>返回值的长度。它对字符串和列表都起作用。</p>
<p>{{ value|length }}</p>
<p>如果value是['a', 'b', 'c', 'd']，那么输出4。</p>
<h3 id="3-filesizeformat">3. filesizeformat</h3>
<p>格式化为“人类可读”文件大小单位（即'13 KB'，4.1 MB'，'102 bytes'等）。</p>
<p>{{ value|filesizeformat }}</p>
<p>如果value是123456789，输出将会是117.7MB。</p>
<p>我们可以创建自定义的模板过滤器和标签，这是最终极的武器。</p>
<h2 id="_4">四、标签</h2>
<p>标签看起来像是这样的： <code>{% tag %}</code>。</p>
<p>标签比变量复杂得多，有些用于在输出中创建文本，有些用于控制循环或判断逻辑，有些用于加载外部信息到模板中供以后的变量使用。</p>
<p>一些标签需要开始和结束标签（即 <code>{％ 标签 ％} ... 标签 内容 ... {％ ENDTAG ％}</code>）。</p>
<p>Django自带了大约24个内置的模版标签。下面是一些常用的标签：</p>
<h3 id="1-for">1. for循环标签</h3>
<p>循环对象中每个元素。需要结束标签<code>{% endfor %}</code> 。例如，显示<code>athlete_list</code>中提供的运动员列表：</p>
<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

<h3 id="2-ifelifelse">2. if，elif和else标签</h3>
<p>计算一个表达式，并且当表达式的值是“True”时，显示块中的内容。需要<code>{% endif %}</code>结束标签。整体逻辑非常类似Python的if、elif和else，如下所示。：</p>
<p>{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}</p>
<p>在上面的例子中，如果<code>athlete_list</code>不是空的，运动员的数量将显示为<code>{{ athlete_list|length }}</code>。否则，如果<code>athlete_in_locker_room_list</code>不为空，将显示“Athletes should be out…”。如果两个列表都是空的，将显示“No athletes.” 。</p>
<p>还可以在if标签中使用过滤器和多种运算符：</p>
<p>{% if athlete_list|length &gt; 1 %}
 Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
 Athlete: {{ athlete_list.0.name }}
{% endif %}</p>
<p>需要注意，大多数模版过滤器都返回字符串类型，所以使用过滤器做整数类型的比较通常是错误的，但length是一个例外。</p>
<h3 id="3-blockextends">3. block和extends标签</h3>
<p>继承和复写模版。类似Python的类继承和重写机制。</p>
<h2 id="_5">五、注释</h2>
<p>要注释模版中一行的部分内容，使用注释语法:<code>{# #}</code>。</p>
<p>例如，下面的模版将被渲染为'hello'：</p>
<p>{# greeting #}hello</p>
<p>注释可以包含任何模版内的代码，有效的或者无效的都可以。 像这样：</p>
<p>{# {% if foo %}bar{% else %} #}</p>
<p>以上是单行注释（在<code>{# .... #}</code>中，不允许有新行）。</p>
<p>如果需要注释掉模版中的多行内容，请使用comment标签。</p>
<h2 id="_6">六、模板继承</h2>
<p>Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承允许你创建一个包含基本“骨架”的父亲模版，它包含站点中的共有元素，并且可以定义能够被子模版覆盖的blocks。</p>
<p>通过下面这个例子，理解模版继承的概念：</p>
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

<p>这个模版，通常被命名为<code>base.html</code>，它定义了一个可以用于两列排版页面的简单HTML骨架。</p>
<p>“子模版”需要做的是先继承父模板<code>base.html</code>，然后复写、填充，或者说实现其中的blocks。</p>
<p>block是在子模版中可能会被覆盖掉的位置。在上面的例子中，block标签定义了三个可以被子模版内容填充的block，分别是title、content和siderbar。</p>
<p>再看下面的例子，子模版可能看起来是这样的：</p>
<p>{% extends "base.html" %}</p>
<p>{% block title %}My amazing blog{% endblock %}</p>
<p>{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}</p>
<p>extends标签是这里的关键。它告诉模版引擎，这个模版“继承”了另一个模版。当模版系统处理这个模版时，首先会去加载父模版，也就是“base.html”。</p>
<p>加载过程中，模版引擎将注意到<code>base.html</code>中的三个block标签，并用子模版中的内容来替换这些block。 根据<code>blog_entries</code>的值，最终输出可能看起来是这样的：</p>
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>My amazing blog</title>
</head>

<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>

    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>

        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

<p>请注意，上面例子中的子模版并没有定义<code>sidebar block</code>，这种情况下，将使用父模版中的内容。父模版的<code>{% block %}</code>标签中的内容总是被用作默认内容。</p>
<p>Django还支持多级继承！常用方式是类似下面的三级结构：</p>
<ul>
<li>创建一个<code>base.html</code>模版，用来控制整个站点的主要视觉和体验。</li>
<li>为站点的每一个app，创建一个<code>base_SECTIONNAME.html</code>模版。 例如<code>base_news.html</code>,<code>base_sports.html</code>。这些模版都继承<code>base.html</code>，并且包含了各自特有的样式和设计。</li>
<li>为每一个页面类型，创建独立的模版，例如新闻内容或者博客文章。 这些模版继承对应app的模版。</li>
</ul>
<p>上面的方式可以使代码得到最大程度的复用，并且使得添加内容到共享的内容区域更加简单，例如app范围内的导航条。</p>
<p>下面是使用继承的一些相关说明：</p>
<ul>
<li>
<p>如果在模版中使用<code>{% extends %}</code>标签，它必须是模版中的第一个标签，必须放在文件首行！</p>
</li>
<li>
<p>在base模版中设置越多的<code>{% block %}</code>标签越好。子模版不必定义全部父模版中的blocks，所以可以在大多数blocks中填充合理的默认内容，然后，只定义你需要的那一个。多一点钩子总比少一点好。</p>
</li>
<li>
<p>如果发现你自己在复制大量重复的模版内容，那意味着你应该把重复的内容移动到父模版中的一个<code>{% block %}</code>中。</p>
</li>
<li>
<p>如果需要获取父模板中的block的内容，可以使用<code>{{ block.super }}</code>变量。如果想要在父block中新增内容而不是完全覆盖它，这将非常有用。使用<code>{{ block.super }}</code> 插入的数据不会被自动转义，因为父模板中的内容已经被转义。</p>
</li>
<li>
<p>在<code>{% block %}</code>之外创建的变量使用模板标签的<code>as</code>语法，不能在块内使用。</p>
</li>
</ul>
<p>例如，下面的模板不会显示任何内容：</p>
<p>{% trans "Title" as title %}
{% block content %}{{ title }}{% endblock %}</p>
<ul>
<li>
<p>为了更好的可读性，可以给<code>{% endblock %}</code>标签一个取名字，像这样：</p>
<p>{% block content %} ...</p>
</li>
</ul>
<p>在大型模版中，这有助于你清楚的看到哪一个<code>{% block %}</code>标签被关闭了。</p>
<ul>
<li>最后，请注意不能在一个模版中定义多个相同名字的block标签。</li>
</ul>
<h2 id="html">七、自动转义HTML</h2>
<p>当从模版中生成HTML文件时，总会存在各种风险，比如xss代码注入等恶意攻击。比如下面的模版片段：</p>
<p>Hello, {{ name }}</p>
<p>首先，它看起来像是无害的，用来显示用户的名字，但是设想一下，如果用户像下面这样输入他的名字，会发生什么：</p>
<script>alert('hello')</script>

<p>使用这个名字的值，模版将会被渲染成这样：</p>
<p>Hello, <script>alert('hello')</script></p>
<p>这意味着浏览器会弹出一个JavaScript警报框！</p>
<p>类似的，如果名字包含一个 '&lt;' 符号（比如下面这样），会发生什么呢？</p>
<p><b>username</p>
<p>这将会导致模版被渲染成这样：</p>
<p>Hello, <b>username</p>
<p>这会导致网页的其余部分被粗体化！</p>
<p>显然，用户提交的数据都被不应该被盲目的信任，并且被直接插入到网页中，因为一个怀有恶意的用户可能会使用这样的漏洞来做一些坏事。 这种类型的安全问题被叫做跨站脚本攻击(Cross Site Scripting）(XSS)。</p>
<p>为避免这个问题，有两个选择：</p>
<ul>
<li>第一，对每个不被信任的值运行escape过滤器，这将把潜在的有害的HTML字符转换成无害的字符串。在Django最初的几年里，这是默认的解决方案，但问题是它将责任放在开发人员/模板作者身上，以确保转义了所有内容，而且很容易忘记转义数据。</li>
<li>
<p>第二，利用Django的自动HTML转义功能。默认情况下，Django中的每个模板会自动转义每个变量。也就是说，下面五个字符将被转义：</p>
</li>
<li>
<p><code>&lt;</code>会转换为<code>&amp;lt;</code></p>
</li>
<li>
<p><code>&gt;</code>会转换为<code>&amp;gt;</code></p>
</li>
<li><code>'</code>（单引号）转换为<code>&amp;#39;</code></li>
<li><code>"</code>(双引号)会转换为<code>&amp;quot;</code></li>
<li><code>&amp;</code>会转换为<code>&amp;amp;</code></li>
</ul>
<p><strong>强烈建议：将第二种功能做为默认打开的设置，不要关闭它！</strong></p>
<p>但是，凡事都有正反两面。有时，模板变量含有一些你打算渲染成原始HTML的数据，你并不想转义这些内容。 例如，你可能会在数据库中储存一些HTML代码，并且直接在模板中嵌入它们。或者，你可能使用Django的模板系统来生成不是HTML的文本 -- 比如邮件信息。要怎么办呢？</p>
<p><strong>对于单个变量</strong>：</p>
<p>使用safe过滤器来关闭变量上的自动转义：</p>
<p>This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}</p>
<p>safe是<code>safe from further escaping</code>或者<code>can be safely interpreted as HTML</code>的缩写。请确保你知道自己在用safe过滤器干什么！在上面的例子中，如果data含有<code>&lt;b&gt;</code>，输出会是：</p>
<p>This will be escaped: &lt;b&gt;
This will not be escaped: <b></p>
<p><strong>对于模板块:</strong></p>
<p>要控制模板上的自动转义，将模板（或者模板中的特定区域）包裹在<code>autoescape</code>标签中，像这样：</p>
<p>{% autoescape off %}
 Hello {{ name }}
{% endautoescape %}</p>
<p>autoescape标签接受on或者off作为它的参数。下面是一个模板的示例：</p>
<p>Auto-escaping is on by default. Hello {{ name }}</p>
<p>{% autoescape off %}
 This will not be auto-escaped: {{ data }}.</p>
<p>Nor this: {{ other_data }}
  {% autoescape on %}
 Auto-escaping applies again: {{ name }}
  {% endautoescape %}
{% endautoescape %}</p>
<p>自动转义标签autoescape还会作用于扩展（extend）了当前模板的模板，以及通过include标签包含的模板，就像所有block标签那样。 看下面的例子：</p>
<p># base.html文件</p>
<p>{% autoescape off %}</p>
<h1>{% block title %}{% endblock %}</h1>
<p>{% block content %}
{% endblock %}
{% endautoescape %}</p>
<p># child.html文件</p>
<p>{% extends "base.html" %}
{% block title %}This &amp; that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}</p>
<p>由于自动转义标签在base模板中关闭，它也会在child模板中关闭，导致当greeting变量含有<code>&lt;b&gt;Hello!&lt;/b&gt;</code>字符串时，会渲染HTML。</p>
<h1>This &amp; that</h1>
<p><b>Hello!</b></p>
<p><strong>过滤器的字符串参数：</strong></p>
<p>之前我们展示过，过滤器的参数可以是字符串：</p>
<p>{{ data|default:"This is a string literal." }}</p>
<p>要注意，所有这种字符串参数在插入模板时都不会进行任何自动转义。原因是，模板的作者可以控制字符串字面值的内容，所以可以确保在模板编写时文本经过正确转义。白话讲，就是，你个程序员对自己传递的参数心里要有数！</p>
<p>也即是说你应该这样编写：</p>
<p>{{ data|default:"3 &lt; 2" }}</p>
<p>而不是：</p>
<p>{{ data|default:"3 &lt; 2" }}  {# 错误的做法#}</p>
<h2 id="_7">八、方法调用</h2>
<p>这部分内容，如果你掌握的极大提高你的模版语言能力。</p>
<p>大多数对象上的方法调用同样可用于模板中。这意味着模板能够访问到的不仅仅是对象的属性（比如字段名称）和视图中传入的变量，还可以执行对象的方法。 例如，Django ORM提供了“entry_set”语法用于查找关联到外键的对象集合。 所以，如果模型“comment”有一个外键关联到模型“task”，可以根据task遍历其所有的comments，像这样：</p>
<p>{% for comment in task.comment_set.all %}
  {{ comment }}
{% endfor %}</p>
<p>与之类似，QuerySets提供了count()方法来计算含有对象的总数。因此，你可以像这样获取所有关于当前任务的评论总数：</p>
<p>{{ task.comment_set.all.count }}</p>
<p>当然，还可以访问已经显式定义在模型上的方法：</p>
<p># models.py
class Task(models.Model):
    def foo(self):
        return "bar"</p>
<p><code>template.html</code></p>
<p>{{ task.foo }}</p>
<p>由于Django有意限制了模板语言中的处理逻辑，不能够在模板中传递参数来调用方法。数据应该在视图中处理，然后传递给模板用于展示。这点不同于Django的ORM操作。</p>
<h2 id="_8">九、多对多调用</h2>
<p>对于如下的模型：</p>
<p>from django.db import models</p>
<p># Create your models here.</p>
<p>class Student(models.Model):
    name = models.CharField(max_length=128)</p>
<p>class Course(models.Model):
    name = models.CharField(max_length=128)
    students = models.ManyToManyField('Student')</p>
<p>模型Course有一个多对多字段指向Student模型。</p>
<h3 id="_9">正向查询</h3>
<p>假设编写了一个如下的视图：</p>
<p>def test(request):
    course = models.Course.objects.get(pk=1)
    return render(request, 'course.html', locals())</p>
<p>获取了id为1的course对象，并将它传递给course.html模版，模版代码如下：</p>
<p>{% for student in course.students.all %}</p>
<p>{{ student.name }}</p>

<p>{% endfor %}</p>
<p>首先通过<code>course.students.all</code>，查寻到course对象关联的students对象集，然后用for标签循环它，获取每个student对象，再用student模型的定义，访问其各个字段的属性。</p>
<h3 id="_10">反向查询</h3>
<p>对于反向查询，从student往course查，假设有如下的视图：</p>
<p>def test2(request):
    student = models.Student.objects.get(pk=1)
    return render(request, 'student.html', locals())</p>
<p>获取了id为1的student对象，并将它传递给student.html模版，模版代码如下：</p>
<p>{% for course in  student.course_set.all %}
{{ course.name }}
{% endfor %}</p>
<p>通过<code>student.course_set.all</code>，反向获取到student实例对应的所有course对象，然后再for标签循环每个course，调用course的各种字段属性。</p>
<p>对于外键ForeignKey，其用法基本类似。只不过正向是<code>obj.fk</code>，且只有1个对像，不是集合。反向则是<code>obj.fk_set</code>，类似多对多。</p>
<h2 id="_11">十、使用自定义标签和过滤器</h2>
<p>某些应用提供了自定义的标签和过滤器。想要在模板中使用它们，首先要确保该应用已经在<code>INSTALLED_APPS</code> 中（比如在下面的例子中，我们添加了'django.contrib.humanize'），之后在模板中使用load标签：</p>
<p>{% load humanize %}
{{ 45000|intcomma }}</p>
<p>上面的例子中， load标签加载了<code>humanize</code>app的标签库，之后我们可以使用它的intcomma过滤器。</p>
<p>如果你开启了<code>django.contrib.admindocs</code>，可以查询admin站点中的文档，查看你安装的自定义库列表。</p>
<p>load标签可以同时接受多个库名称，由空格分隔。 例如：</p>
<p>{% load humanize i18n %}</p>
<p><strong>自定义库和模板继承：</strong></p>
<p>当你加载一个自定义标签或过滤器库时，标签或过滤器只在当前模板中有效--并不是带有模板继承关系的任何父模板或者子模版中都有效。白话说就是，你在父模板中可能加载了自定义标签，然并卵，你在子模版中还要再加载一次！</p>
<p>例如，如果一个模板<code>foo.html</code>带有<code>{% load humanize %}</code>，子模版（例如，带有<code>{% extends "foo.html" %}</code>）中不能访问humanize模板标签和过滤器。 子模版需要再添加自己的<code>{% load humanize %}</code>。</p>
<p>这个特性是出于保持可维护性和逻辑性的目的。</p>
<hr />
<p><a href="/course/django/144"> 第三章：模版层</a> <a href="/course/django/146">Django内置模板标签 </a></p>
<hr />
<h4 id="14">评论总数： 14</h4>
<hr />
<p><a href="https://api.weibo.com/oauth2/authorize?client_id=3191049160&amp;response_type=code&amp;redirect_uri=http://www.liujiangblog.com/login?next=/course/django/145">点击登录后方可评论</a></p>
<hr />
<p>很好！</p>
<p>By   Pamljam    On   <em>2023年1月9日 16:35</em>   <a href="/reply/2571">回复</a></p>
<p>精彩</p>
<p>By   sfin禾页    On   <em>2021年2月7日 16:12</em>   <a href="/reply/2368">回复</a></p>
<p>打卡</p>
<p>By   多浪的河流    On   <em>2020年11月7日 14:29</em>   <a href="/reply/2261">回复</a></p>
<p>def test(request): course = models.Course.objects.get(pk=1) return render(request, 'course.html', locals()) 刘老师，这里面的local()是什么意思啊？</p>
<p>By   GardenBaby_    On   <em>2020年1月12日 18:19</em>   <a href="/reply/1841">回复</a></p>
<p>locals() 函数会以字典类型返回当前位置的全部局部变量。</p>
<p>蹦巴拉蹦巴拉蹦   回复   GardenBaby_ <em>2020年6月5日 22:45</em>   <a href="/reply/2099">回复</a></p>
<p>觉得学习应该是循序渐进，从易到难，这样一下子全部展开真的有点接受不了</p>
<p>By   定期换名字啦啦    On   <em>2019年3月21日 05:15</em>   <a href="/reply/1170">回复</a></p>
<p>这里相当于是速查手册了，你需要先按照“第一个Django应用”这一节的内容熟悉Django的流程和基本原理，然后再来看这里拓展，这样就好理解了，或者你可以百度找一篇django搭建博客实例，然后对照代码来这里学习。</p>
<p>学到老单到老   回复   定期换名字啦啦 <em>2019年4月9日 11:29</em>   <a href="/reply/1233">回复</a></p>
<p>后来自己做了一些项目之后，现在回过头来看，这章居然全部看懂了，好开心，谢谢刘老师。 建议刚开始学习的时候要不求甚解，不要纠结，了解怎么一回事，然后放在心里继续往下面看。 提几个小建议，翻译有点生硬。 在“七、自动转义HTML”里，可以告诉读者name的值为“”“”<script>alert('hello')</script>“”“”“”，而不是“如果用户像下面这样输入他的名字”，那样的话有些读者不知道这个script里的含义是什么。 “”八、方法调用 这部分内容，如果你掌握的极大提高你的模版语言能力。“”应该是如果你掌握，将极大提高你的模板语言能力。</p>












                
              </article>
            </div>
          
          
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
    <div class="md-copyright__highlight">
      Copyright 2024 Write By Heng
    </div>
  
  
</div>
      
        <div class="md-social">
  
    
    
    
    
      
      
    
    <a href="http://home.liheng.work/" target="_blank" rel="noopener" title="home.liheng.work" class="md-social__link">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9zm135.9 197.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM340.8 177c6.6 2.8 11.5 9.2 22.7 22.1 2-1.4 7.5-5.2 7.5-8.6 0-4.9-11.8-13.2-13.2-23 11.2-5.7 25.2-6 37.6-8.9 68.1-16.4 116.3-52.9 146.8-116.7C548.3 29.3 554 16.1 554.6 2l-2 2.6c-28.4 50-33 63.2-81.3 100-31.9 24.4-69.2 40.2-106.6 54.6l-6.3-.3v-21.8c-19.6 1.6-19.7-14.6-31.6-23-18.7 20.6-31.6 40.8-58.9 51.1-12.7 4.8-19.6 10-25.9 21.8 34.9-16.4 91.2-13.5 98.8-10zM555.5 0l-.6 1.1-.3.9.6-.6zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46.1v27.2l11.8-3.4-2.9-23.8zm-68.7-150.4 24.1 61.2 21-13.8-31.3-50.9zm84.4 154.9 2 12.4c9-1.5 58.4-6.6 58.4-14.1 0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3z"/></svg>
    </a>
  
    
    
    
    
      
      
    
    <a href="https://github.com/lmliheng?tab=repositories" target="_blank" rel="noopener" title="github.com" class="md-social__link">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    
    
    <script id="__config" type="application/json">{"base": ".", "features": ["content.code.copy", "content.code.select"], "search": "assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}}</script>
    
    
      <script src="assets/javascripts/bundle.dd8806f2.min.js"></script>
      
    
  </body>
</html>